/*******************************************************************************
 *                              Cerebro.java                                   *
 *                           Cesar Himura Elric                                *
 *                              JavaCup 2009                                   *
 *******************************************************************************/

package org.javahispano.javacup.tacticas_aceptadas.Himura;

import java.util.List;

public class Cerebro
{
    /**
     * Obtiene la distancia entre dos puntos
     * @param x1 Coordenada en x del punto 1
     * @param y1 Coordenada en y del punto 1
     * @param x2 Coordenada en x del punto 2
     * @param y2 Coordenada en y del punto 2
     * @return La distancia entre dos puntos
     */
    public double getDistancia(double x1, double y1, double x2, double y2){
        return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
    }

    /**
     * Obtiene la ecuación de una recta a partir de dos puntos
     * @param x1 Coordenada X del Primer Punto de la Recta
     * @param y1 Coordenada Y del Primer Punto de la Recta
     * @param x2 Coordenada X del Segundo Punto de la Recta
     * @param y2 Coordenada Y del Segundo Punto de la Recta
     * @return Los Coeficientes de la ecuación de la Recta
     */
    public double[] getRecta(double x1, double y1, double x2, double y2)
    {
        double[] ecuacion = new double[3];

        ecuacion[0] = 1;

        ecuacion[1] = (y1 - y2)/(x1 - x2);

        //ecuacion[2] = ecuacion[1] * x1 + y1;
        ecuacion[2] = y1 - (ecuacion[1] * x1);

        return ecuacion;
    }

    public double[] getCircunferencia(double x, double y, double r)
    {
        double[] ecuacion = new double[5];

        x = x * -1;
        y = y * -1;

        double[] b = desarrollaBinomio(1, x);

        for(int index = 0; index < b.length; index++)
        {
            ecuacion[index] = b[index];
        }

        b = desarrollaBinomio(1, y);

        ecuacion[4] = ecuacion[2] + b[2] + Math.pow(r, 2) * -1;
        ecuacion[2] = b[0];
        ecuacion[3] = b[1];

        return ecuacion;
    }

    private double[] desarrollaBinomio(double a, double b)
    {
        double[] binomio = new double[3];

        binomio[0] = Math.pow(a, 2);
        binomio[1] = a * b * 2;
        binomio[2] = Math.pow(b, 2);

        return binomio;
    }

    public double[] getSolucionEcSegundoGrado(double a, double b, double c)
    {
        double[] x = new double[2];

        x[0] = (-1 * b + Math.sqrt((Math.pow(b, 2) - (4 * a * c))))/(2 * a);
        x[1] = (-1 * b - Math.sqrt((Math.pow(b, 2) - (4 * a * c))))/(2 * a);

        return x;
    }

    public boolean intersectaRectaCircunferencia(double[] recta, double[] circunferencia)
    {
        double[] ecuacionSimple = new double[3];

        double[] b = desarrollaBinomio(recta[1], recta[2]);

        ecuacionSimple[0] = circunferencia[0] + b[0];
        ecuacionSimple[1] = circunferencia[1] + b[1];
        ecuacionSimple[2] = circunferencia[4] + b[2];

        ecuacionSimple[1] += circunferencia[3] * recta[1];
        ecuacionSimple[2] += circunferencia[3] * recta[2];

        double[] x = getSolucionEcSegundoGrado(ecuacionSimple[0], ecuacionSimple[1], ecuacionSimple[2]);
        for(int index = 0; index < x.length; index++)
        {
            if(Double.isNaN(x[index]))
            {
                return false;
            }
        }

        return true;
    }

    /**
     * Hace un redondeo hacia arriba, la funcion se utiliza para aplicar la gravedad sobre el
     * balon cuando este va en el aire
     * @param valor
     * @param divisor
     * @return
     */
    public double round(double valor, double divisor)
    {
        return Math.round(valor / divisor) * divisor;
    }

    /**
     * Pasa una Lista a un array multidimensional
     * @param list Lista a de arrays double que se convertira
     * @return
     */
    public double[][] toArray(List<double[]> list)
    {
        int cols = list.get(0).length;

        double[][] array = new double[list.size()][cols];

        for(int index = 0; index < list.size(); index++)
        {
            array[index] = list.get(index);
        }

        return array;
    }

    /**
     * Ordena un Array de acuerdo a las distancias
     * @param jd Array que contiene el indice de los jugadores con su distancia
     * @return El Array ordenado de acuerdo a las distancias
     */
    public double[][] ordenaArrayDistancias(double[][] jd, int cols)
    {
        //double aux = 0.0;
        //double auxN = 0.0;
        double[] c = new double[cols];

        for(int i = 0; i < cols; i++)
            c[i] = 0d;

        //**** ordena los jugadores dependiendo las distancias *******
        for(int i = 0; i < jd.length; i++)
            for(int j = 0; j < jd.length - 1; j++)
                //if(jd[j][1] > jd[j + 1][1])
                if(jd[j][cols-1] > jd[j + 1][cols-1])
                {
                    /*aux = jd[j][0];
                    auxN = jd[j][1];
                    jd[j][0] = jd[j + 1][0];
                    jd[j][1] = jd[j + 1][1];
                    jd[j + 1][0] = aux;
                    jd[j + 1][1] = auxN;*/

                    for(int col = 0; col < cols; col++)
                    {
                        c[col] = jd[j][col];
                        jd[j][col] = jd[j + 1][col];
                        jd[j + 1][col] = c[col];
                    }
                }

        return jd;
    }
}